<template>
	<div class="container flex items-center h-full pl-2 py-1" :style="{ ...container }">
		<div class="ml-2" :style="{ textAlign: props.config.style.align }">
			<span class="font-7" :style="{ ...titleStyle }" v-if="!props.config.style.dataUp">{{
				formState.title.value
			}}</span>
			<div :style="{ ...dataStyle }">
				{{ formState.numValue.value }}
			</div>
			<span class="font-7" :style="{ ...titleStyle }" v-if="props.config.style.dataUp">{{
				formState.title.value
			}}</span>
		</div>
		<div ref="chart" class="chart"></div>
	</div>
</template>
<script setup>
	import config from './config'
	import * as echarts from 'echarts'
	import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
	import datasetApi from '@/views/plugin/dashboard/api/datasetApi'
	import { designStore } from '@/views/plugin/dashboard/store'
	const useDesignStore = designStore()
	import { cloneDeep } from 'lodash-es'

	const props = defineProps({
		config: {
			type: Object,
			default: () => config
		}
	})
	const formState = ref(cloneDeep(config.data))
	// 数据源 --- 调接口
	const dataSource = ref({})
	// 旧的dataSetJson 用于比较是否一样就不重新获取数据
	const oldDataSetJson = ref(props.config.dataSetConfig.dataSetJson)
	// 图表配置
	const chartOptions = ref({})

	// 获取数据源数据函数
	const fetchChartData = async (isFlag = false) => {
		const { dataSetType, dataSetJson } = props.config.dataSetConfig
		const isNew = isFlag || JSON.stringify(oldDataSetJson.value) !== JSON.stringify(dataSetJson)

		// 如果是静态数据
		formState.value = props.config.data
		if (dataSetType === 0) return

		// 如果是数据源且有效
		if (dataSetType === 1 && dataSetJson && Object.keys(dataSetJson).length > 0 && isNew) {
			// 更新值
			oldDataSetJson.value = dataSetJson
			// 模拟接口返回下拉数据
			await datasetApi.preview(newVal).then((res) => {
				dataSource.value = res[0] || {}
				formState.value.title.value = dataSource.value[props.config.data.title?.field] || ''
				formState.value.numValue.value = dataSource.value[props.config.data.numValue?.field] || ''
				formState.value.chart.value = dataSource.value[props.config.data.chart.field] || ''
			})
		}
	}

	// 设置数据
	const setChartOptions = () => {
		chartOptions.value = {
			labelLine: {
				show: false
			},
			grid: {
				top: 10,
				right: 0,
				bottom: 10,
				left: 0,
				containLabel: true
			},
			xAxis: {
				type: 'category',
				axisLabel: { show: false }, // 隐藏X轴刻度线
				splitLine: { show: false }, // 隐藏X轴网格线
				axisLine: { show: false }, // 隐藏X轴刻度线
				axisTick: { show: false } // 隐藏X轴刻度线
			},
			yAxis: {
				type: 'value',
				axisLabel: { show: false }, // 隐藏X轴刻度线
				splitLine: { show: false } // 隐藏X轴网格线
			},
			series: [
				{
					type: props.config.style.chartType === 'ring' ? 'pie' : props.config.style.chartType,
					data: formState.value.chart.value || [],
					itemStyle: {
						color: ['pie', 'ring'].includes(props.config.style.chartType) ? null : props.config.style.chartColor,
						borderRadius: 1
					},
					barWidth: '20%',
					barGap: '100%',
					labelLine: false,
					showSymbol: false,
					smooth: true,
					padAngle: 5,
					areaStyle: {
						opacity: 0.8,
						color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
							{
								offset: 0,
								color: props.config.style.chartColor + '80',
								opacity: 0.8
							},
							{
								offset: 0.8,
								color: props.config.style.chartColor + '03',
								opacity: 0.01
							}
						])
					},
					radius: props.config.style.chartType === 'ring' ? ['60%', '100%'] : ['0%', '100%']
				}
			]
		}
	}

	const chart = ref(null)
	const myChart = ref(null)
	// 初始化图表
	const initChart = async () => {
		await nextTick()
		if (chart.value && !myChart.value) {
			myChart.value = markRaw(echarts.init(chart.value))
			myChart.value.setOption(chartOptions.value)
		}
	}

	const resizeObserver = ref(null)

	//  处理图表尺寸变化
	const handleResize = () => {
		if (myChart.value) {
			myChart.value.resize()
		}
	}

	onMounted(async () => {
		await onReload()
		// 使用ResizeObserver监听容器尺寸变化
		if (chart.value) {
			resizeObserver.value = new ResizeObserver(() => {
				handleResize()
			})
			resizeObserver.value.observe(chart.value)
		}
	})
	const onReload = async (isFlag = false) => {
		// 获取数据
		await fetchChartData(isFlag)
		// 初始化图表配置
		setChartOptions()

		// 更新图表
		if (myChart.value) {
			await nextTick(() => {
				myChart.value.setOption(chartOptions.value)
			})
		} else {
			await initChart()
		}
	}

	onBeforeUnmount(() => {
		if (myChart.value) {
			myChart.value.dispose()
		}
		// 清理ResizeObserver
		if (resizeObserver.value) {
			resizeObserver.value.disconnect()
		}
	})
	defineExpose({ onReload })
	// 样式
	const container = computed(() => ({
		padding: `${props.config.style.paddingT}px ${props.config.style.paddingR}px ${props.config.style.paddingB}px ${props.config.style.paddingL}px`,
		justifyContent: props.config.style.iconPosition === 'left' ? props.config.style.contentPosition : 'space-between',
		background: props.config.style.bgColor,
		borderColor: props.config.style.borderColor,
		borderWidth: props.config.style.borderWidth + 'px',
		borderStyle: props.config.style.borderStyle,
		borderTopLeftRadius: props.config.style.bgRTL + 'px',
		borderTopRightRadius: props.config.style.bgRTR + 'px',
		borderBottomLeftRadius: props.config.style.bgRBL + 'px',
		borderBottomRightRadius: props.config.style.bgRBR + 'px',
		boxShadow: `${props.config.style.shadowX}px ${props.config.style.shadowY}px ${props.config.style.shadowDegree}px ${props.config.style.shadowColor}`
	}))
	const titleStyle = computed(() => ({
		fontSize: props.config.style.titleSize + 'px',
		color: props.config.style.titleColor,
		fontWeight: props.config.style.titleWeight ? 800 : 500,
		fontStyle: props.config.style.titleStyle ? 'italic' : '',
		textDecoration: props.config.style.titleLine ? 'underline' : ''
	}))
	const dataStyle = computed(() => ({
		fontSize: props.config.style.dataSize + 'px',
		color: props.config.style.dataColor,
		fontWeight: props.config.style.dataWeight ? 800 : 500,
		fontStyle: props.config.style.dataStyle ? 'italic' : '',
		textDecoration: props.config.style.dataLine ? 'underline' : '',
		marginTop: !props.config.style.dataUp ? props.config.style.spacing + 'px' : '0px',
		marginBottom: props.config.style.dataUp ? props.config.style.spacing + 'px' : '0px'
	}))
	const iconBoxStyle = computed(() => ({
		display: props.config.style.iconShow ? 'flex' : 'none',
		backgroundColor: props.config.style.iconBgColor,
		height: props.config.style.iconBgSize + 'px',
		width: props.config.style.iconBgSize + 'px',
		borderTopLeftRadius: props.config.style.iconRTL + 'px',
		borderTopRightRadius: props.config.style.iconRTR + 'px',
		borderBottomLeftRadius: props.config.style.iconRBL + 'px',
		borderBottomRightRadius: props.config.style.iconRBR + 'px'
	}))
</script>

<style scoped lang="less">
	.container {
		padding: 20px;
	}
	.chart {
		height: 100%;
		width: 40%;
		min-height: 70px;
		min-width: 120px;
	}
</style>
